package mop.model;

import java.util.LinkedList;
import java.util.List;

import mop.util.event.PropertyChangeEvent;
import mop.util.event.PropertyChangeListener;

/**
 * Class for property change support
 * This makes it easy for models to act as an observable object that fires events when changed
 * 
 * @author 	MOP Team 7
 */
public class PropertyChangeSupport {
	
	/**
	 * Model we support
	 */
	private final ModelInterface model;
	
	/**
	 * Listeners observing this model for property changes
	 */
	private final List<PropertyChangeListener> listeners;
	
	/**
	 * Constructor
	 * 
	 * @param 	model	Observable model
	 * 
	 * @post	model is set to given value
	 * 	|this.model == model
	 * @post	listener list is initialized
	 * 	|this.listeners != null
	 */
	public PropertyChangeSupport(ModelInterface model)
	{
		this.model = model;
		this.listeners = new LinkedList<PropertyChangeListener>();
	}
	
	/**
	 * Add a property change listener
	 * @param 	listener	Property change listener
	 * @effect	Given listener is added to list of listeners
	 * 	|listeners.add(listener)
	 */
	public void addPropertyChangeListener(PropertyChangeListener listener){
		listeners.add(listener);
	}

	/**
	 * Remove a property change listener
	 * @param 	listener	Property change listener
	 * @effect	Given listener is removed from list of listeners
	 * 	|listeners.remove(listener)
	 */
    public void removePropertyChangeListener(PropertyChangeListener listener){
    	listeners.remove(listener);
    }
	
    /**
     * Notify all listeners of a property change in the model
     * @effect	All listeners get notified
     * 	|for(PropertyChangeListener l : this.listeners)
     * 	|	listener.handlePropertyChange(e)
     */
	public void firePropertyChange()
	{
		PropertyChangeEvent e =  new PropertyChangeEvent(this.model);
		for(PropertyChangeListener l : this.listeners)
			l.handlePropertyChange(e);
	}
}
